package com.willwinder.universalgcodesender.firmware.g2core;

import java.util.Arrays;
import java.util.Optional;

/**
 * <a href="https://github.com/synthetos/g2/blob/edge-preview/g2core/error.h">Error codes</a>
 */
public enum G2CoreStatusCode {
    STAT_OK(0, "OK"),
    STAT_ERROR(1, "Error"),
    STAT_EAGAIN(2, "Eagain"),
    STAT_NOOP(3, "No operation performed"),
    STAT_COMPLETE(4, "Completed operation"),
    STAT_SHUTDOWN(5, "System shutdown"),
    STAT_PANIC(6, "System panic"),
    STAT_EOL(7, "End of line"),
    STAT_EOF(8, "End of file"),
    STAT_FILE_NOT_OPEN(9, "File not open"),
    STAT_FILE_SIZE_EXCEEDED(10, "Max file size exceeded"),
    STAT_NO_SUCH_DEVICE(11, "No such device"),
    STAT_BUFFER_EMPTY(12, "Buffer empty"),
    STAT_BUFFER_FULL(13, "Buffer full non-fatal"),
    STAT_BUFFER_FULL_FATAL(14, "Buffer full FATAL"),
    STAT_INITIALIZING(15, "Initializing"),
    STAT_ENTERING_BOOT_LOADER(16, "Entering boot loader"),
    STAT_FUNCTION_IS_STUBBED(17, "Function is stubbed"),
    STAT_ALARM(18, "System alarm"),
    STAT_NO_DISPLAY(19, "19"),
    STAT_INTERNAL_ERROR(20, "Internal error"),
    STAT_INTERNAL_RANGE_ERROR(21, "Internal range error"),
    STAT_FLOATING_POINT_ERROR(22, "Floating point error"),
    STAT_DIVIDE_BY_ZERO(23, "Divide by zero"),
    STAT_INVALID_ADDRESS(24, "Invalid Address"),
    STAT_READ_ONLY_ADDRESS(25, "Read-only address"),
    STAT_INIT_FAILURE(26, "Initialization failure"),
    STAT_ERROR_27(27, "27"),
    STAT_FAILED_TO_GET_PLANNER_BUFFER(28, "Failed to get planner buffer"),
    STAT_GENERIC_EXCEPTION_REPORT(29, "Generic exception report"),
    STAT_PREP_LINE_MOVE_TIME_IS_INFINITE(30, "Move time is infinite"),
    STAT_PREP_LINE_MOVE_TIME_IS_NAN(31, "Move time is NAN"),
    STAT_FLOAT_IS_INFINITE(32, "Float is infinite"),
    STAT_FLOAT_IS_NAN(33, "Float is NAN"),
    STAT_PERSISTENCE_ERROR(34, "Persistence error"),
    STAT_BAD_STATUS_REPORT_SETTING(35, "Bad status report setting"),
    STAT_FAILED_GET_PLANNER_BUFFER(36, "Failed to get planner buffer"),
    STAT_ERROR_37(37, "Backplan hit running buffer"),
    STAT_ERROR_38(38, "38"),
    STAT_ERROR_39(39, "39"),
    STAT_ERROR_40(40, "40"),
    STAT_ERROR_41(41, "41"),
    STAT_ERROR_42(42, "42"),
    STAT_ERROR_43(43, "43"),
    STAT_ERROR_44(44, "44"),
    STAT_ERROR_45(45, "45"),
    STAT_ERROR_46(46, "46"),
    STAT_ERROR_47(47, "47"),
    STAT_ERROR_48(48, "48"),
    STAT_ERROR_49(49, "49"),
    STAT_ERROR_50(50, "50"),
    STAT_ERROR_51(51, "51"),
    STAT_ERROR_52(52, "52"),
    STAT_ERROR_53(53, "53"),
    STAT_ERROR_54(54, "54"),
    STAT_ERROR_55(55, "55"),
    STAT_ERROR_56(56, "56"),
    STAT_ERROR_57(57, "57"),
    STAT_ERROR_58(58, "58"),
    STAT_ERROR_59(59, "59"),
    STAT_ERROR_60(60, "60"),
    STAT_ERROR_61(61, "61"),
    STAT_ERROR_62(62, "62"),
    STAT_ERROR_63(63, "63"),
    STAT_ERROR_64(64, "64"),
    STAT_ERROR_65(65, "65"),
    STAT_ERROR_66(66, "66"),
    STAT_ERROR_67(67, "67"),
    STAT_ERROR_68(68, "68"),
    STAT_ERROR_69(69, "69"),
    STAT_ERROR_70(70, "70"),
    STAT_ERROR_71(71, "71"),
    STAT_ERROR_72(72, "72"),
    STAT_ERROR_73(73, "73"),
    STAT_ERROR_74(74, "74"),
    STAT_ERROR_75(75, "75"),
    STAT_ERROR_76(76, "76"),
    STAT_ERROR_77(77, "77"),
    STAT_ERROR_78(78, "78"),
    STAT_ERROR_79(79, "79"),
    STAT_ERROR_80(80, "80"),
    STAT_ERROR_81(81, "81"),
    STAT_ERROR_82(82, "82"),
    STAT_ERROR_83(83, "83"),
    STAT_ERROR_84(84, "84"),
    STAT_ERROR_85(85, "85"),
    STAT_SPINDLE_ASSERTION_FAILURE(86, "Spindle assertion failure"),
    STAT_EXEC_ALINE_ASSERTION_FAILURE(87, "mp_exec_aline() assertion failure"),
    STAT_BUFFER_FREE_ASSERTION_FAILURE(88, "Buffer free assertion failure"),
    STAT_STATE_MANAGEMENT_ASSERTION_FAILURE(89, "State management assertion failure"),
    STAT_CONFIG_ASSERTION_FAILURE(90, "Config assertion failure"),
    STAT_XIO_ASSERTION_FAILURE(91, "XIO assertion failure"),
    STAT_ENCODER_ASSERTION_FAILURE(92, "Encoder assertion failure"),
    STAT_STEPPER_ASSERTION_FAILURE(93, "Stepper assertion failure"),
    STAT_PLANNER_ASSERTION_FAILURE(94, "Planner assertion failure"),
    STAT_CANONICAL_MACHINE_ASSERTION_FAILURE(95, "Canonical machine assertion failure"),
    STAT_CONTROLLER_ASSERTION_FAILURE(96, "Controller assertion failure"),
    STAT_STACK_OVERFLOW(97, "Stack overflow detected"),
    STAT_MEMORY_FAULT(98, "Memory fault detected"),
    STAT_GENERIC_ASSERTION_FAILURE(99, "Generic assertion failure"),
    STAT_UNRECOGNIZED_NAME(100, "Unrecognized command or config name"),
    STAT_INVALID_OR_MALFORMED_COMMAND(101, "Invalid or malformed command"),
    STAT_BAD_NUMBER_FORMAT(102, "Bad number format"),
    STAT_UNSUPPORTED_TYPE(103, "Unsupported number or JSON type"),
    STAT_PARAMETER_IS_READ_ONLY(104, "Parameter is read-only"),
    STAT_PARAMETER_CANNOT_BE_READ(105, "Parameter cannot be read"),
    STAT_COMMAND_NOT_ACCEPTED(106, "Command not accepted"),
    STAT_INPUT_EXCEEDS_MAX_LENGTH(107, "Input exceeds max length"),
    STAT_INPUT_LESS_THAN_MIN_VALUE(108, "Input less than minimum value"),
    STAT_INPUT_EXCEEDS_MAX_VALUE(109, "Input exceeds maximum value"),
    STAT_INPUT_VALUE_RANGE_ERROR(110, "Input value range error"),
    STAT_JSON_SYNTAX_ERROR(111, "JSON syntax error"),
    STAT_JSON_TOO_MANY_PAIRS(112, "JSON has too many pairs"),
    STAT_JSON_OUTPUT_TOO_LONG(113, "JSON string too long"),
    STAT_NESTED_TXT_CONTAINER(114, "JSON txt fields cannot be nested"),
    STAT_MAX_DEPTH_EXCEEDED(115, "JSON maximum nesting depth exceeded"),
    STAT_VALUE_TYPE_ERROR(116, "JSON value does not agree with variable type"),
    STAT_INPUT_FROM_MUTED_CHANNEL_ERROR(117, "Input from a muted channel was ignored"),
    STAT_CHECKSUM_MATCH_FAILED(118, "The provided checksum didn't match"),
    STAT_LINE_NUMBER_OUT_OF_SEQUENCE(119, "The provided line number was out of sequence"),
    STAT_MISSING_LINE_NUMBER_WITH_CHECKSUM(120, "120"),
    STAT_ERROR_121(121, "121"),
    STAT_ERROR_122(122, "122"),
    STAT_ERROR_123(123, "123"),
    STAT_ERROR_124(124, "124"),
    STAT_ERROR_125(125, "125"),
    STAT_ERROR_126(126, "126"),
    STAT_ERROR_127(127, "127"),
    STAT_ERROR_128(128, "128"),
    STAT_ERROR_129(129, "129"),
    STAT_GCODE_GENERIC_INPUT_ERROR(130, "Generic Gcode input error"),
    STAT_GCODE_COMMAND_UNSUPPORTED(131, "Gcode command unsupported"),
    STAT_MCODE_COMMAND_UNSUPPORTED(132, "M code unsupported"),
    STAT_GCODE_MODAL_GROUP_VIOLATION(133, "Gcode modal group violation"),
    STAT_AXIS_IS_MISSING(134, "Axis word missing"),
    STAT_AXIS_CANNOT_BE_PRESENT(135, "Axis cannot be present"),
    STAT_AXIS_IS_INVALID(136, "Axis invalid for this command"),
    STAT_AXIS_IS_NOT_CONFIGURED(137, "Axis disabled"),
    STAT_AXIS_NUMBER_IS_MISSING(138, "Axis target position missing"),
    STAT_AXIS_NUMBER_IS_INVALID(139, "Axis target position invalid"),
    STAT_ACTIVE_PLANE_IS_MISSING(140, "Selected plane missing"),
    STAT_ACTIVE_PLANE_IS_INVALID(141, "Selected plane invalid"),
    STAT_FEEDRATE_NOT_SPECIFIED(142, "Feedrate not specified"),
    STAT_INVERSE_TIME_MODE_CANNOT_BE_USED(143, "Inverse time mode cannot be used with this command"),
    STAT_ROTARY_AXIS_CANNOT_BE_USED(144, "Rotary axes cannot be used with this command"),
    STAT_GCODE_G53_WITHOUT_G0_OR_G1(145, "G0 or G1 must be active for G53"),
    STAT_REQUESTED_VELOCITY_EXCEEDS_LIMITS(146, "Requested velocity exceeds limits"),
    STAT_CUTTER_COMPENSATION_CANNOT_BE_ENABLED(147, "Cutter compensation cannot be enabled"),
    STAT_PROGRAMMED_POINT_SAME_AS_CURRENT_POINT(148, "Programmed point same as current point"),
    STAT_SPINDLE_SPEED_BELOW_MINIMUM(149, "Spindle speed below minimum"),
    STAT_SPINDLE_SPEED_MAX_EXCEEDED(150, "Spindle speed exceeded maximum"),
    STAT_SPINDLE_MUST_BE_OFF(151, "Spindle must be off for this command"),
    STAT_SPINDLE_MUST_BE_TURNING(152, "Spindle must be turning for this command"),
    STAT_ARC_SPECIFICATION_ERROR(153, "Arc specification error"),
    STAT_ARC_HAS_IMPOSSIBLE_CENTER_POINT(154, "Arc specification error - impossible center point"),
    STAT_ARC_HAS_ROTARY_AXIS(155, "Arc specification error - arc has rotary axis(es)"),
    STAT_ARC_AXIS_MISSING_FOR_SELECTED_PLANE(156, "Arc specification error - missing axis(es)"),
    STAT_ARC_OFFSETS_MISSING_FOR_SELECTED_PLANE(157, "Arc specification error - missing offset(s)"),
    STAT_ARC_RADIUS_OUT_OF_TOLERANCE(158, "Arc specification error - radius arc out of tolerance"),
    STAT_ARC_ENDPOINT_IS_STARTING_POINT(159, "Arc specification error - endpoint is starting point"),
    STAT_P_WORD_IS_MISSING(160, "P word missing"),
    STAT_P_WORD_IS_INVALID(161, "P word invalid"),
    STAT_P_WORD_IS_ZERO(162, "P word zero"),
    STAT_P_WORD_IS_NEGATIVE(163, "P word negative"),
    STAT_P_WORD_IS_NOT_AN_INTEGER(164, "P word not an integer"),
    STAT_P_WORD_IS_NOT_VALID_TOOL_NUMBER(165, "P word not a valid tool number"),
    STAT_D_WORD_IS_MISSING(166, "D word missing"),
    STAT_D_WORD_IS_INVALID(167, "D word invalid"),
    STAT_E_WORD_IS_MISSING(168, "E word missing"),
    STAT_E_WORD_IS_INVALID(169, "E word invalid"),
    STAT_H_WORD_IS_MISSING(170, "H word missing"),
    STAT_H_WORD_IS_INVALID(171, "H word invalid"),
    STAT_L_WORD_IS_MISSING(172, "L word missing"),
    STAT_L_WORD_IS_INVALID(173, "L word invalid"),
    STAT_Q_WORD_IS_MISSING(174, "Q word missing"),
    STAT_Q_WORD_IS_INVALID(175, "Q word invalid"),
    STAT_R_WORD_IS_MISSING(176, "R word missing"),
    STAT_R_WORD_IS_INVALID(177, "R word invalid"),
    STAT_S_WORD_IS_MISSING(178, "S word missing"),
    STAT_S_WORD_IS_INVALID(179, "S word invalid"),
    STAT_T_WORD_IS_MISSING(180, "T word missing"),
    STAT_T_WORD_IS_INVALID(181, "T word invalid"),
    STAT_ERROR_182(182, "182"),
    STAT_ERROR_183(183, "183"),
    STAT_ERROR_184(184, "184"),
    STAT_ERROR_185(185, "185"),
    STAT_ERROR_186(186, "186"),
    STAT_ERROR_187(187, "187"),
    STAT_ERROR_188(188, "188"),
    STAT_ERROR_189(189, "189"),
    STAT_ERROR_190(190, "190"),
    STAT_ERROR_191(191, "191"),
    STAT_ERROR_192(192, "192"),
    STAT_ERROR_193(193, "193"),
    STAT_ERROR_194(194, "194"),
    STAT_ERROR_195(195, "195"),
    STAT_ERROR_196(196, "196"),
    STAT_ERROR_197(197, "197"),
    STAT_ERROR_198(198, "198"),
    STAT_ERROR_199(199, "199"),
    STAT_GENERIC_ERROR(200, "Generic error"),
    STAT_MINIMUM_LENGTH_MOVE(201, "Move < min length"),
    STAT_MINIMUM_TIME_MOVE(202, "Move < min time"),
    STAT_LIMIT_SWITCH_HIT(203, "Limit hit [$clear to reset, $lim=0 to override]"),
    STAT_COMMAND_REJECTED_BY_ALARM(204, "Command rejected by ALARM [$clear to reset]"),
    STAT_COMMAND_REJECTED_BY_SHUTDOWN(205, "Command rejected by SHUTDOWN [$clear to reset]"),
    STAT_COMMAND_REJECTED_BY_PANIC(206, "Command rejected by PANIC [^x to reset]"),
    STAT_KILL_JOB(207, "Kill job"),
    STAT_NO_GPIO(208, "No GPIO for this value"),
    STAT_TEMPERATURE_CONTROL_ERROR(209, "209"),
    STAT_G29_NOT_CONFIGURED(210, "Marlin G29 command was not configured at compile-time"),
    STAT_ERROR_211(211, "211"),
    STAT_ERROR_212(212, "212"),
    STAT_ERROR_213(213, "213"),
    STAT_ERROR_214(214, "214"),
    STAT_ERROR_215(215, "215"),
    STAT_ERROR_216(216, "216"),
    STAT_ERROR_217(217, "217"),
    STAT_ERROR_218(218, "218"),
    STAT_ERROR_219(219, "219"),
    STAT_SOFT_LIMIT_EXCEEDED(220, "Soft limit"),
    STAT_SOFT_LIMIT_EXCEEDED_XMIN(221, "Soft limit - X min"),
    STAT_SOFT_LIMIT_EXCEEDED_XMAX(222, "Soft limit - X max"),
    STAT_SOFT_LIMIT_EXCEEDED_YMIN(223, "Soft limit - Y min"),
    STAT_SOFT_LIMIT_EXCEEDED_YMAX(224, "Soft limit - Y max"),
    STAT_SOFT_LIMIT_EXCEEDED_ZMIN(225, "Soft limit - Z min"),
    STAT_SOFT_LIMIT_EXCEEDED_ZMAX(226, "Soft limit - Z max"),
    STAT_SOFT_LIMIT_EXCEEDED_AMIN(227, "Soft limit - A min"),
    STAT_SOFT_LIMIT_EXCEEDED_AMAX(228, "Soft limit - A max"),
    STAT_SOFT_LIMIT_EXCEEDED_BMIN(229, "Soft limit - B min"),
    STAT_SOFT_LIMIT_EXCEEDED_BMAX(230, "Soft limit - B max"),
    STAT_SOFT_LIMIT_EXCEEDED_CMIN(231, "Soft limit - C min"),
    STAT_SOFT_LIMIT_EXCEEDED_CMAX(232, "Soft limit - C max"),
    STAT_SOFT_LIMIT_EXCEEDED_ARC(233, "Soft limit during arc"),
    STAT_ERROR_234(234, "234"),
    STAT_ERROR_235(235, "235"),
    STAT_ERROR_236(236, "236"),
    STAT_ERROR_237(237, "237"),
    STAT_ERROR_238(238, "238"),
    STAT_ERROR_239(239, "239"),
    STAT_HOMING_CYCLE_FAILED(240, "Homing cycle failed"),
    STAT_HOMING_ERROR_BAD_OR_NO_AXIS(241, "Homing Err - Bad or no axis specified"),
    STAT_HOMING_ERROR_ZERO_SEARCH_VELOCITY(242, "Homing Err - Search velocity is zero"),
    STAT_HOMING_ERROR_ZERO_LATCH_VELOCITY(243, "Homing Err - Latch velocity is zero"),
    STAT_HOMING_ERROR_TRAVEL_MIN_MAX_IDENTICAL(244, "Homing Err - Travel min & max are the same"),
    STAT_HOMING_ERROR_NEGATIVE_LATCH_BACKOFF(245, "245"),
    STAT_HOMING_ERROR_HOMING_INPUT_MISCONFIGURED(246, "Homing Err - Homing input is misconfigured"),
    STAT_HOMING_ERROR_MUST_CLEAR_SWITCHES_BEFORE_HOMING(247, "Homing Err - Must clear switches before homing"),
    STAT_ERROR_248(248, "248"),
    STAT_ERROR_249(249, "249"),
    STAT_PROBE_CYCLE_FAILED(250, "Probe cycle failed"),
    STAT_PROBE_TRAVEL_TOO_SMALL(251, "Probe travel is too small"),
    STAT_NO_PROBE_INPUT_CONFIGURED(252, "No probe switch configured"),
    STAT_MULTIPLE_PROBE_SWITCHES_CONFIGURED(253, "Multiple probe switches configured"),
    STAT_PROBE_IS_ALREADY_TRIPPED(254, "Probe is already tripped"),
    STAT_ERROR_255(255, "255");

    private final int code;
    private final String message;

    G2CoreStatusCode(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public static Optional<G2CoreStatusCode> fromCode(int code) {
        return Arrays.stream(values()).filter(status -> status.code == code).findFirst();
    }

    public int getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }
}
